/**
 * This file is Copyright © 2008 Software Craftsmen Limited. All Rights Reserved.
 */
package com.softwarecraftsmen.functors;

import org.jetbrains.annotations.NotNull;

import java.util.concurrent.Callable;

public abstract class NullaryReturningFunctor<R>
{
	@NotNull
	public abstract R closure();

	@NotNull
	public final NullaryReturningFunctor<R> curry()
	{
		return this;
	}

	@NotNull
	public Callable<R> toCallable()
	{
		return new Callable<R>()
		{
			@NotNull
			public R call() throws Exception
			{
				return closure();
			}
		};
	}

	@NotNull
	public static <R> NullaryReturningFunctor<R> fromCallable(final @NotNull Callable<R> callable)
	{
		return new NullaryReturningFunctor<R>()
		{
			@NotNull
			public R closure()
			{
				try
				{
					return callable.call();
				}
				catch (Exception e)
				{
					throw new RuntimeException(e);
				}
			}
		};
	}


	@NotNull
	public final Runnable toRunnable()
	{
		return new Runnable()
		{
			public void run()
			{
				closure();
			}
		};
	}

	@NotNull
	public static NullaryReturningFunctor<Nothing> fromRunnable(final @NotNull Runnable runnable)
	{
		return new NullaryReturningFunctor<Nothing>()
		{
			@NotNull
			public Nothing closure()
			{
				runnable.run();
				return Nothing.Nothing;
			}
		};
	}

}
